﻿using LJX.SmartPark.Domain.Base;
using LJX.SmartPark.Domain.IotInfo;
using LJX.SmartPark.EntityFramework;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LJX.SmartPark.Service.Repository
{
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : KeyEntity
    {
        private readonly StudentServerContext _smartLabServerContext;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public Repository(StudentServerContext smartLabServerContext, IHttpContextAccessor httpContextAccessor)
        {
            _smartLabServerContext = smartLabServerContext;
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task<int> DeleteAsync(params TEntity[] entities)
        {
            foreach (var entity in entities)
            {
                //SetDeletor(entity, GetUserId());
            }

            return await _smartLabServerContext.SaveChangesAsync();
        }

        public async Task<int> DeleteByIdAsync(KeyEntity key)
        {
            var entity = await _smartLabServerContext.Set<TEntity>().FindAsync(key.Id);
            if (entity != null)
            {
                //SetDeletor(entity, GetUserId());
                _smartLabServerContext.Entry(entity).State = EntityState.Deleted;
                return await _smartLabServerContext.SaveChangesAsync();
            }

            return default;
        }

        public async Task<List<TEntity>> GetAllListAsync()
        {
            return await _smartLabServerContext.Set<TEntity>().ToListAsync();
        }

        public IQueryable<TEntity> GetListQuery()
        {
            return _smartLabServerContext.Set<TEntity>().AsQueryable();
        }

        public int GetCount()
        {
            return _smartLabServerContext.Set<TEntity>().Count();
        }

        public async Task<int> InsertAsync(params TEntity[] entities)
        {
            if (entities == null || entities.Length == 0)
            {
                return default;
            }

            int userId = GetUserId();
            foreach (var entity in entities)
            {
                SetCreator(entity, userId);
            }
            await _smartLabServerContext.Set<TEntity>().AddRangeAsync(entities);

            return await _smartLabServerContext.SaveChangesAsync();
        }

        public async Task<TEntity> GetEntityByIdAsync(KeyEntity key)
        {
            return await _smartLabServerContext.FindAsync<TEntity>(key.Id);
        }

        public async Task<int> InsertAsyncById(TEntity entity)
        {
            //SetCreator(entity, GetUserId());
            _smartLabServerContext.Set<TEntity>().Add(entity);

            return await _smartLabServerContext.SaveChangesAsync();
        }

        public async Task<int> UpdateAsync(TEntity entity)
        {
            //SetEditor(entity, GetUserId());
            _smartLabServerContext.Entry(entity).State = EntityState.Modified;
            return await _smartLabServerContext.SaveChangesAsync();
        }

        /// <summary>
        /// 设置创建用户的信息
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="userId"></param>
        private void SetCreator(TEntity entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Creator = userId;
                    baseEntity.CreateTime = DateTime.Now;
                }
            }
        }

        public void SetDeletor(TEntity entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Deletor = userId;
                    baseEntity.DeleteTime = DateTime.Now;
                    baseEntity.IsDelete = 1;
                    _smartLabServerContext.Set<TEntity>().Update(entity);
                }
                else
                {
                    _smartLabServerContext.Set<TEntity>().Remove(entity);
                }
            }
        }

        public void SetEditor(TEntity entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Editor = userId;
                    baseEntity.EditTime = DateTime.Now;
                }
            }
        }

        private int GetUserId() =>
             Convert.ToInt32(_httpContextAccessor.HttpContext.User.Claims
             .FirstOrDefault(c => c.Type == JwtRegisteredClaimNames.Jti)?.Value
             ?? throw new Exception("用户未登录"));

    }
}
